package com.jackrain.nea.omslocal.Dao;

import com.alibaba.dubbo.common.utils.NetUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.util.TypeUtils;
import com.jackrain.nea.config.PropertiesConf;
import com.jackrain.nea.omslocal.service.GetSqunceService;
import com.jackrain.nea.omslocal.service.LocalLogService;
import com.jackrain.nea.omslocal.service.SendMqServies;
import com.jackrain.nea.omslocal.util.JsonKeyCheck;
import com.jackrain.nea.omslocal.util.PackageJsonSqlUtil;
import com.jackrain.nea.omslocal.util.RegexDateUtil;
import com.jackrain.nea.util.ApplicationContextHandle;
import com.jackrain.nea.util.Tools;
import com.jackrain.nea.web.query.QueryEngine;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.time.FastDateFormat;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.text.ParseException;
import java.util.*;

/**
 * @Discription: 京东订单下载
 * Created with IntelliJ IDEA.
 * @Author cs
 * @Date 2018/4/26 15:15
 */
@Slf4j
@Component
public class JingDongOrderDao {


    @Autowired
    private RegexDateUtil regexDate;
    @Autowired
    private LocalLogService localLogService;
    private FastDateFormat fastformat = FastDateFormat.getInstance("yyyy-MM-dd HH:mm:ss");
    @Autowired
    private SendMqServies sendMq;
    @Autowired
    private GetSqunceService getSqunceService;
    @Autowired
    private PackageJsonSqlUtil packageJsonSqlUtil;
    @Autowired
    private SendMqServies sendMqServies;


    /**
     * 保存京东订单
     *
     * @param tempObj
     * @param msgkey
     * @param topic
     */
    public void orderstart(JSONObject tempObj, String msgkey, String topic,String tag) {
        JingDongOrderDao jingDongOrderDao = ApplicationContextHandle.getBean(JingDongOrderDao.class);
        PropertiesConf pconf = ApplicationContextHandle.getBean("propertiesConf");
        String jdLogRetTopic = pconf.getProperty("ons.jdLogRetTopic","");
        // 回执 jsonobj
        JSONObject retObj = new JSONObject();
        int countFaild = 0;
        String sellerNick = null;
        String tids = "";
        // 定义 接收 订单 orderId
        List orderIds = new ArrayList();

        JSONArray tempArr = tempObj.getJSONArray("orderInfoList");
        if (tempArr == null || tempArr.isEmpty()) {
            // 订单数据为空, 不需操作
            log.debug("京东订单数据为空, msgkey : " + msgkey);
            return;
        }

        for (Object obj : tempArr) {

            Long orderId = 0L;
            // 订单数据, 订单商品数据 , 订单优惠数据,  收货人数据, 电子面单数据
            JSONObject orderObj = null;
            JSONArray itemInfoList = null;
            JSONArray couponDetailList = null;
            JSONObject consigneeInfo = null;
            JSONObject orderPrintdata = null;
            String orderStatus = null;
            try {


                // 循环遍历jsonarr, 插入数据
                orderObj = JSONObject.parseObject(obj.toString(), Feature.OrderedField);
                sellerNick = orderObj.getString("nick");
                itemInfoList = orderObj.getJSONArray("itemInfoList");
                couponDetailList = orderObj.getJSONArray("couponDetailList");
                consigneeInfo = orderObj.getJSONObject("consigneeInfo");
                orderPrintdata = orderObj.getJSONObject("orderPrintData");
                orderId = orderObj.getLong("orderId");
                orderStatus = orderObj.getString("orderState");
                tids += ","+orderId;
                // 根据 平台 订单 id 查询数据库,判断该数据是 新增 或是 修改
                String selectSql = "SELECT id FROM T_OMSJINGDONGORDER WHERE ORDER_ID = ?";
                int id = Tools.getInt(QueryEngine.getInstance().doQueryOne(selectSql, new Object[]{orderId}), -1);
                if (id < 0) {
                    // 数据不存在, 新增订单
                    jingDongOrderDao.insert(orderObj, itemInfoList, couponDetailList, consigneeInfo, orderPrintdata);
                } else {
                    // 数据存在,根据查询的id 更新数据
                    jingDongOrderDao.update(orderObj, itemInfoList, couponDetailList, consigneeInfo, orderPrintdata, id);

                }
                localLogService.insertLogForJd(null,orderId.toString(),topic,msgkey,sellerNick,orderStatus,0);
            } catch (Exception e) {
                // 发生异常,处理
                // 获取流
                StringWriter sw = new StringWriter();
                PrintWriter pw = new PrintWriter(sw);
                // 逐条将错误信息以消息发送到线上发送到线上
                JSONObject errObj = new JSONObject();
                errObj.put("flag",0);
                errObj.put("platid", orderId);
                errObj.put("sellernick", sellerNick);
                errObj.put("topic", topic);
                errObj.put("tag", tag);
                errObj.put("msgkey", msgkey);
                // 线下消费报错的主机 ip
                errObj.put("ip", NetUtils.getLocalAddress());
                // 将错误以流写出
                e.printStackTrace(pw);
                errObj.put("errmsg", sw.toString());
                errObj.put("sendtime", System.currentTimeMillis());
                try {
                    sendMqServies.sendMqObj(errObj, pconf.getProperty("ons.jdLogErrTopic"), tag);
                } catch (Exception e1) {
                    e1.printStackTrace();
                    log.debug("京东订单发送错误信息失败");
                }
                log.debug("订单插入失败 : tid :" + orderId + "msgkey : " + msgkey + sw.toString());
                // 处理异常  1.将错误信息发送到线上  2. 将错误信息保存到本地数据库
                countFaild++;
                // 插入本地错误
                localLogService.insertLogForJd(e.getMessage(),orderId.toString(),topic,msgkey,sellerNick,orderStatus,1);
            }

        }
        tids = tids.substring(1);
        retObj.put("flag",0);
        retObj.put("tag",tag);
        retObj.put("sellernick",sellerNick);
        retObj.put("msgkey",msgkey);
        retObj.put("msgsize",tempArr.size());
        retObj.put("topic",topic);
        retObj.put("tids",tids);
        retObj.put("successcount",tempArr.size()-countFaild);
        retObj.put("failedcount",countFaild);
        try {
            sendMqServies.sendMqRetLogObj(retObj,jdLogRetTopic,tag,sellerNick);
        } catch (Exception e) {
            e.printStackTrace();
            log.debug("京东订单发送回执信息失败");
        }
    }

    /**
     * 新增京东订单数据
     *
     * @param orderObj
     * @param itemInfoList
     * @param couponDetailList
     * @param consigneeInfo
     */
    @Transactional(rollbackFor = Exception.class)
    public void insert(JSONObject orderObj, JSONArray itemInfoList, JSONArray couponDetailList, JSONObject consigneeInfo, JSONObject orderPrintdata) throws ParseException {

        Object outId = null;
        // 新增数据
        // 数据不为空 保存数据
        if (orderObj != null || orderObj.isEmpty()) {
            Map map = null;
            map = saveJdOrder(orderObj, orderPrintdata);
            outId = map.get("seq");
        } else {
            log.debug("主表数据为空 id " + outId);
        }

        if (itemInfoList != null) {

            saveSku(itemInfoList, outId);

        } else {
            log.debug("drders 订单商品明细数据为空 id " + outId);
        }

        if (couponDetailList != null) {

            saveCouponDTai(couponDetailList, outId);

        } else {
            log.debug("drders 订单优惠数据为空 ID " + outId);
        }

        if (consigneeInfo != null) {

            saveUser(consigneeInfo, outId);
        } else {
            log.debug("drders 订单收货人信息数据为空 id + " + outId);
        }

        // 在执行完之后需要更改主表的 istrans 字段为 0
        String sql = "update T_OMSJINGDONGORDER SET istrans = 0 WHERE id = ?";
        QueryEngine.getInstance().executeUpdate(sql, new Object[]{outId});

    }

    /**
     * 修改订单数据
     *
     * @param orderObj
     * @param itemInfoList
     * @param couponDetailList
     * @param consigneeInfo
     * @param id
     */
    @Transactional(rollbackFor = Exception.class)
    public void update(JSONObject orderObj, JSONArray itemInfoList, JSONArray couponDetailList, JSONObject consigneeInfo, JSONObject orderPrintdata, int id) throws ParseException {

        if (orderObj != null) {
            // 根据查询到的 id 更新主表数据
            this.updateJdOrder(orderObj, orderPrintdata, id);
        } else {
            log.error("主表数据为空");
        }

        // 更新操作之后需要更新 istrans 为0
        String sql = "update T_OMSJINGDONGORDER SET istrans = 0 WHERE id = ?";
        QueryEngine.getInstance().executeUpdate(sql, new Object[]{id});

    }


    /**
     * 保存订单主表数据
     *
     * @param orderObj
     * @param orderPrintdata
     * @return
     */
    public HashMap saveJdOrder(JSONObject orderObj, JSONObject orderPrintdata) throws ParseException {

        HashMap map = new HashMap();
        String orderTableName = "T_OMSJINGDONGORDER";
        synchronized (this) {
            // 校验字段, 拼接字段, 修改 key
            JsonKeyCheck checkjson = (JsonKeyCheck) ApplicationContextHandle.getBean(JsonKeyCheck.class);
            orderObj = checkjson.checkJsonkeycache(orderObj, orderTableName, checkjson.getInsertcolsmap());
            orderObj = this.chekOrderJsonCloums(orderObj, orderPrintdata);
        }
        long id = getSqunceService.getSqunce(orderTableName);
        orderObj.put("id", id);
        Object[] objArr = orderObj.values().toArray();

        String columnName = packageJsonSqlUtil.packageInsertCloumnName(orderObj);
        String columnValue = packageJsonSqlUtil.packageInsertColumnValue(objArr);

        String sql = "insert into T_OMSJINGDONGORDER (" + columnName + ") values (" + columnValue + ")";
        int code = QueryEngine.getInstance().executeUpdate(sql, objArr);

        map.put("code", code);
        map.put("seq", id);

        return map;
    }

    /**
     * 保存订单商品数据
     *
     * @param itemInfoList
     * @param outId
     */
    public void saveSku(JSONArray itemInfoList, Object outId) throws ParseException {

        String productTableName = "T_OMSJINGDONGPRODUCT";

        for (Object obj : itemInfoList) {
            JSONObject productObj = JSONObject.parseObject(obj.toString(), Feature.OrderedField);
            synchronized (this) {
                // 校验字段, 拼接字段, 修改 key
                JsonKeyCheck checkjson = (JsonKeyCheck) ApplicationContextHandle.getBean(JsonKeyCheck.class);
                productObj = checkjson.checkJsonkeycache(productObj, productTableName, checkjson.getInsertcolsmap());
                productObj = this.chekProductJsonCloums(productObj);
            }

            // 获取子表的 sequences , 添加 必须字段
            long id = getSqunceService.getSqunce(productTableName);
            productObj.put("id", id);
            productObj.put("omsjingdongorderid", outId);
            Object[] objArr = productObj.values().toArray();
            // 拼接 sql
            String columnName = packageJsonSqlUtil.packageInsertCloumnName(productObj);
            String columnValue = packageJsonSqlUtil.packageInsertColumnValue(objArr);

            String sql = "insert into T_OMSJINGDONGPRODUCT (" + columnName + ") values (" + columnValue + ")";
            log.debug("插入京东订单商品子表 sql : " + sql);
            int code = QueryEngine.getInstance().executeUpdate(sql, objArr);

        }

    }

    /**
     * 保存订单优惠数据
     *
     * @param couponDetailList
     * @param outId
     */
    public void saveCouponDTai(JSONArray couponDetailList, Object outId) throws ParseException {
        String couponTableName ="T_OMSJDCOUPONDTAI";

        for (Object obj : couponDetailList) {
            JSONObject couponObj = JSONObject.parseObject(obj.toString(), Feature.OrderedField);
            synchronized (this) {
                // 校验字段, 拼接字段, 修改 key
                JsonKeyCheck checkjson = ApplicationContextHandle.getBean(JsonKeyCheck.class);
                couponObj = checkjson.checkJsonkeycache(couponObj, couponTableName, checkjson.getInsertcolsmap());
                couponObj = this.chekCouponJsonCloums(couponObj);
            }

            // 获取子表的 sequences , 添加 必须字段
            long id = getSqunceService.getSqunce(couponTableName);
            couponObj.put("id", id);
            couponObj.put("sysorderid", outId);
            Object[] objArr = couponObj.values().toArray();
            // 拼接 sql
            String columnName = packageJsonSqlUtil.packageInsertCloumnName(couponObj);
            String columnValue = packageJsonSqlUtil.packageInsertColumnValue(objArr);

            String sql = "insert into T_OMSJDCOUPONDTAI (" + columnName + ") values (" + columnValue + ")";
            log.debug("插入京东订单优惠子表 sql : " + sql);
            int code = QueryEngine.getInstance().executeUpdate(sql, objArr);

        }

    }

    /**
     * 保存订单收货人数据
     *
     * @param consigneeInfo
     * @param outId
     */
    public void saveUser(JSONObject consigneeInfo, Object outId) throws ParseException {

        String userTableName = "T_OMSJINGDONGUSER";
        synchronized (this) {
            // 校验字段, 拼接字段, 修改 key
            JsonKeyCheck checkjson = ApplicationContextHandle.getBean(JsonKeyCheck.class);
            consigneeInfo = checkjson.checkJsonkeycache(consigneeInfo, userTableName, checkjson.getInsertcolsmap());
            consigneeInfo = this.chekUserJsonCloums(consigneeInfo);
        }
        // 获取子表的 sequences , 添加 必须字段
        long id = getSqunceService.getSqunce(userTableName);
        consigneeInfo.put("id", id);
        consigneeInfo.put("sysorderid", outId);
        Object[] objArr = consigneeInfo.values().toArray();
        // 拼接 sql
        String columnName = packageJsonSqlUtil.packageInsertCloumnName(consigneeInfo);
        String columnValue = packageJsonSqlUtil.packageInsertColumnValue(objArr);

        String sql = "insert into T_OMSJINGDONGUSER (" + columnName + ") values (" + columnValue + ")";
        log.debug("插入京东订单收货人子表 sql : " + sql);
        int code = QueryEngine.getInstance().executeUpdate(sql, objArr);

    }


    /**
     * 修改订单主表数据
     *
     * @param orderObj
     * @param orderPrintdata
     * @return
     */
    public void updateJdOrder(JSONObject orderObj, JSONObject orderPrintdata, long id) throws ParseException {
        HashMap map = new HashMap();
        String orderTableName = "T_OMSJINGDONGORDER";

        synchronized (this) {
            // 校验字段, 拼接字段, 修改 key
            JsonKeyCheck checkjson = ApplicationContextHandle.getBean(JsonKeyCheck.class);
            orderObj = checkjson.checkJsonkeycache(orderObj, orderTableName, checkjson.getUpdatecolsmap());
            orderObj = this.chekOrderJsonCloums(orderObj,orderPrintdata);
        }

        String params = packageJsonSqlUtil.packageUpdateCloumnName(orderObj);
        Object[] objArr =packageJsonSqlUtil.packageUpdateColumnValue(orderObj);

        String sql = "update T_OMSJINGDONGORDER set " + params + " where id = ?";
        int code = QueryEngine.getInstance().executeUpdate(sql, ArrayUtils.add(objArr, id));

    }

    /**
     * 修改订单商品数据
     *
     * @param itemInfoList
     * @param outId
     */
    public void updateSku(JSONArray itemInfoList, Object outId) {

    }

    /**
     * 修改订单优惠数据
     *
     * @param couponDetailList
     * @param outId
     */
    public void updateCouponDTai(JSONArray couponDetailList, Object outId) {

    }

    /**
     * 修改订单收货人数据
     *
     * @param consigneeInfo
     * @param outId
     */
    public void updateUser(JSONObject consigneeInfo, Object outId) {


    }


    /**
     * 拼接订单 json
     */
    private JSONObject chekOrderJsonCloums(JSONObject jsonObject, JSONObject orderPrintdata) {

        String paymentConfirmTime = jsonObject.getString("paymentConfirmTime");
        jsonObject.remove("paymentConfirmTime");
        log.debug("=========" + paymentConfirmTime);
        if (null != paymentConfirmTime) {
            jsonObject.put("payment_Confirm_Time", paymentConfirmTime);
        }

        String orderRemark = jsonObject.getString("orderRemark");
        jsonObject.remove("orderRemark");
        if (null != orderRemark) {
            jsonObject.put("order_Remark", orderRemark);
        }

        String invoiceInfo = jsonObject.getString("invoiceInfo");
        jsonObject.remove("invoiceInfo");
        if (null != invoiceInfo) {
            jsonObject.put("invoice_Info", invoiceInfo);
        }

        String deliveryType = jsonObject.getString("deliveryType");
        jsonObject.remove("deliveryType");
        if (null != deliveryType) {
            jsonObject.put("delivery_Type", deliveryType);
        }

        String orderStateRemark = jsonObject.getString("orderStateRemark");
        jsonObject.remove("orderStateRemark");
        if (null != orderStateRemark) {
            jsonObject.put("order_State_Remark", orderStateRemark);
        }

        String storeorder = jsonObject.getString("storeOrder");
        jsonObject.remove("storeOrder");
        if (null != storeorder) {
            jsonObject.put("store_Order", storeorder);
        }


        String orderState = jsonObject.getString("orderState");
        jsonObject.remove("orderState");
        if (null != orderState) {
            jsonObject.put("order_State", orderState);
        }

        String payType = jsonObject.getString("payType");
        jsonObject.remove("payType");
        if (null != payType) {
            jsonObject.put("pay_Type", payType);
        }

        String orderId = jsonObject.getString("orderId");
        jsonObject.remove("orderId");
        if (null != orderId) {
            jsonObject.put("order_Id", orderId);
        }

        String venderId = jsonObject.getString("venderId");
        jsonObject.remove("venderId");
        if (null != venderId) {
            jsonObject.put("vender_Id", venderId);
        }

        String sellerDiscount = jsonObject.getString("sellerDiscount");
        jsonObject.remove("sellerDiscount");
        if (null != sellerDiscount) {
            jsonObject.put("seller_Discount", sellerDiscount);
        }

        String freightPrice = jsonObject.getString("freightPrice");
        jsonObject.remove("freightPrice");
        if (null != freightPrice) {
            jsonObject.put("freight_Price", freightPrice);
        }

        String orderSellerPrice = jsonObject.getString("orderSellerPrice");
        jsonObject.remove("orderSellerPrice");
        if (null != orderSellerPrice) {
            jsonObject.put("order_Seller_Price", orderSellerPrice);
        }

        String orderPayment = jsonObject.getString("orderPayment");
        jsonObject.remove("orderPayment");
        if (null != orderPayment) {
            jsonObject.put("order_Payment", orderPayment);
        }


        String orderTotalPrice = jsonObject.getString("orderTotalPrice");
        jsonObject.remove("orderTotalPrice");
        if (null != orderTotalPrice) {
            jsonObject.put("order_Total_Price", orderTotalPrice);
        }

        String orderEndTime = jsonObject.getString("orderEndTime");
        jsonObject.remove("orderEndTime");
        if (null != orderEndTime) {
            jsonObject.put("order_End_Time", orderEndTime);
        }

        String orderStartTime = jsonObject.getString("orderStartTime");
        jsonObject.remove("orderStartTime");
        if (null != orderStartTime) {
            jsonObject.put("order_Start_Time", orderStartTime);
        }


        if (null != orderPrintdata) {

            String payment_typeStr = orderPrintdata.getString("payment_typeStr");
            if (null != payment_typeStr) {
                jsonObject.put("payment_typeStr", payment_typeStr);
            }


            String should_pay = orderPrintdata.getString("should_pay");
            if (null != should_pay){
                jsonObject.put("should_pay", should_pay);
            }


            String partner = orderPrintdata.getString("partner");
            if (null != partner){
                jsonObject.put("partner", partner);
            }

            String sorting_code = orderPrintdata.getString("sorting_code");
            if (null != sorting_code){
                jsonObject.put("sorting_code", sorting_code);
            }


            String cky2_name = orderPrintdata.getString("cky2_name");
            if (null != cky2_name){
                jsonObject.put("cky2_name", cky2_name);
            }

            String bf_deli_good_glag = orderPrintdata.getString("bf_deli_good_glag");
            if (null != bf_deli_good_glag){
                jsonObject.put("bf_deli_good_glag", bf_deli_good_glag);
            }


        } else {
            log.debug("面单数据为空");
        }

        return jsonObject;
    }


    /**
     * 拼接商品 json
     */
    private JSONObject chekProductJsonCloums(JSONObject jsonObject) {

        String productNo = jsonObject.getString("productNo");
        jsonObject.remove("productNo");
        jsonObject.put("product_No", productNo);

        String wareId = jsonObject.getString("wareId");
        jsonObject.remove("wareId");
        jsonObject.put("ware_Id", wareId);

        String skuName = jsonObject.getString("skuName");
        jsonObject.remove("skuName");
        jsonObject.put("sku_Name", skuName);

        String outerSkuId = jsonObject.getString("outerSkuId");
        jsonObject.remove("outerSkuId");
        jsonObject.put("outer_Sku_Id", outerSkuId);

        String skuId = jsonObject.getString("skuId");
        jsonObject.remove("skuId");
        jsonObject.put("sku_Id", skuId);

        String jdPrice = jsonObject.getString("jdPrice");
        jsonObject.remove("jdPrice");
        jsonObject.put("jd_Price", jdPrice);

        String itemTotal = jsonObject.getString("itemTotal");
        jsonObject.remove("itemTotal");
        jsonObject.put("item_Total", itemTotal);

        String giftPoint = jsonObject.getString("giftPoint");
        jsonObject.remove("giftPoint");
        jsonObject.put("gift_Point", giftPoint);

        return jsonObject;
    }

    /**
     * 拼接优惠 json
     */
    private JSONObject chekCouponJsonCloums(JSONObject jsonObject) {

        String couponPrice = jsonObject.getString("couponPrice");
        jsonObject.remove("couponPrice");
        jsonObject.put("coupon_Price", couponPrice);

        String couponType = jsonObject.getString("couponType");
        jsonObject.remove("couponType");
        jsonObject.put("coupon_Type", couponType);

        String orderId = jsonObject.getString("orderId");
        jsonObject.remove("orderId");
        jsonObject.put("order_Id", orderId);

        String skuId = jsonObject.getString("skuId");
        jsonObject.remove("skuId");
        jsonObject.put("sku_Id", skuId);

        return jsonObject;
    }

    /**
     * 拼接收货人 json
     */
    private JSONObject chekUserJsonCloums(JSONObject jsonObject) {

        String fullAddress = jsonObject.getString("fullAddress");
        jsonObject.remove("fullAddress");
        jsonObject.put("full_Address", fullAddress);
        return jsonObject;
    }

}
